import { Injectable } from '@nestjs/common';
import { PrismaService } from 'nestjs-prisma';
import {ApiException} from "../../common/exceptions/api.exception";
import {AddDemoDto, ImportDemoDto, UpdateDemoDto} from "./dto/req-demo.dto";
import {specsAddData} from "../specs/dto/demo-item.dto";
import { ResponseUtil } from "../../utils/response.util";
import {ExcelOptionAll} from "../common/excel/excel.interface";
import {EXCEL_ARR_KRY} from "../common/excel/excel.constant";
import {ExcelTypeEnum} from "../common/excel/excel.enum";

@Injectable()
export class DemoService {
  constructor(
    private readonly prisma: PrismaService
  ) {}

  async findAll() {
    return this.prisma.projectList.findMany({
      include: { specs: true, dimensions: true },
      where: { isDeleted: false },
      
    });
  }

  async add(addDemoDto: AddDemoDto) {
    const { projectName = '' } = addDemoDto;
    // 1. 检查 projectName 是否已存在
    const existingProject = await this.prisma.projectList.findFirst({
      where: { projectName: projectName, isDeleted: false },
    });

    if (existingProject) {
      throw new ApiException(
        `项目 "${projectName}" 已存在`
      );
    }
    return await this.prisma.projectList.create({
      data: {
        ...addDemoDto,
        specs: {
          create: specsAddData
        },
        dimensions: {
          create: {
            createBy: 'admin',
            createTime: new Date(),
          }
        }
      },
      include: { specs: true, dimensions: true },
    });
  }

  async findItemById(projectId: Number) {
    try {
      let data = await this.prisma.projectList.findFirst({
        where: { projectId: Number(projectId) },
        include: {
          specs: true,
          dimensions: true
        }
      });
      // data.specs = data.specs && data.specs.length > 0 ? data.specs[0] : {}
      // data.dimensions = data.dimensions && data.dimensions.length > 0 ? data.dimensions[0] : {}
      return ResponseUtil.success(data);
    } catch (error) {
      return ResponseUtil.error('查询失败', error);
    }
  }

  async update(updateDemoDto: UpdateDemoDto) {
    return await this.prisma.$transaction(async (prisma) => {
      const { projectId, projectName = ''  } = updateDemoDto
      const project = await prisma.projectList.findUnique({
        where: {
          projectId
        }
      })
      if (!project) throw new ApiException('该项目不存在，请刷新后重试。');

      const existingProject = await prisma.projectList.findFirst({
        where: {
          projectName,
          isDeleted: false
        }
      })
      if (existingProject) throw new ApiException(`项目 "${projectName}" 已存在`);

      return await prisma.projectList.update({
        data: updateDemoDto,
        where: {
          projectId,
        }
      })
    })
  }

  /* 删除 */
  async softDeleteProject(projectId: number) {
    return this.prisma.$transaction([
      // 1. 软删除项目
      this.prisma.projectList.update({
        where: { projectId },
        data: {
          isDeleted: true,
          deletedAt: new Date()
        }
      }),

    ]);
  }

  /* 删除 */
  async delete(projectId: number) {
    return await this.prisma.$transaction(async (prisma) => {
      const menu = await prisma.projectList.findUnique({
        where: {
          projectId,
        },
      });
      if (!menu) throw new ApiException('该项目不存在，请刷新后重试。');
      await prisma.projectList.delete({
        where: {
          projectId,
        },
      });

      await prisma.projectSpecs.deleteMany({
        where: {
          projectId,
        },
      });

      await prisma.projectDimension.deleteMany({
        where: {
          projectId,
        },
      });
    });
  }

  /* 导入产品列表 */
  async importData(importDemoDtoArr: ImportDemoDto[]) {

    return await this.prisma.$transaction(async (prisma) => {
      const importObjArr: ExcelOptionAll[] =
        Reflect.getMetadata(EXCEL_ARR_KRY, ImportDemoDto) ?? [];
      const excelData = await this.formatImport(importObjArr);
      const fieldMap = {}
      excelData[1].forEach((item, index) => {
        fieldMap[item] = excelData[0][index]
      })
      for (const item of importDemoDtoArr) {
        let newData: ImportDemoDto = {} as ImportDemoDto
        Object.keys(item).forEach((key) => {
          newData[fieldMap[key]] = item[key] || ''
          if (typeof newData[fieldMap[key]] === 'number') {
            newData[fieldMap[key]] = `${newData[fieldMap[key]]}`
          }
        })
        const project = await prisma.projectList.findFirst({
          where: {
            projectName: newData.projectName,
          },
        });
        if (!project) {
          console.log(newData, 'project')
          await this.prisma.projectList.create({
            data: {
              ...newData,
              specs: {
                create: {
                  ...specsAddData
                }
              },
              dimensions: {
                create: {
                  createBy: 'admin',
                  createTime: new Date(),
                }
              }
            },
            include: { specs: true, dimensions: true },
          });
        }
      }
    });
  }

  private async formatImport(importObjArr: ExcelOptionAll[]): Promise<[][]> {
    const optionArr: ExcelOptionAll[] = importObjArr
      .filter(
        (item) =>
          item.type === ExcelTypeEnum.ALL || item.type === ExcelTypeEnum.IMPORT,
      ) //过滤
      .sort((obj, obj2) => obj.sort - obj2.sort); //排序
    const data = [];
    data.push(optionArr.map((item) => item.propertyKey));
    data.push(optionArr.map((item) => item.name));
    return data;
  }
}
